package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tanhua.autoconfig.template.AipFaceTemplate;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.constants.Constants;
import com.tanhua.commons.utils.JwtUtils;
import com.tanhua.dubbo.api.RecommendUserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.UserLikeApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Userlike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.*;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Xiao
 * @date 2021/10/22
 */
@Service
@Slf4j
public class UserInfoService {
    @DubboReference
    private UserInfoApi userInfoApi;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private AipFaceTemplate aipFaceTemplate;
    @DubboReference
    private VisitorsApi visitorsApi;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @DubboReference
    private UserLikeApi userLikeApi;
    @DubboReference
    private RecommendUserApi recommendUserApi;
    @Autowired
    private TanhuaService tanhuaService;

    /**
     * 保存用户资料
     * @param userInfo
     * @param token
     */
    public boolean save(UserInfo userInfo, String token) {
        /*//判断token是否合法
        boolean verifyToken = JwtUtils.verifyToken(token);
        if (!verifyToken) {
            return false;
        }*/
        //设置userInfo的id：用户id
        /*Claims claims = JwtUtils.getClaims(token);
        Integer id = (Integer) claims.get("id");*/
        //userInfo.setId(Long.valueOf(id));
        userInfo.setId(UserHolder.getUserId());
        //存储userInfo
        userInfoApi.save(userInfo);
        return true;
    }

    /**
     * 更新头像
     *
     * @param headPhoto
     * @return
     */
    public boolean updateHead(MultipartFile headPhoto) throws IOException {
        /*//判断token是否合法
        boolean verifyToken = JwtUtils.verifyToken(token);
        if (!verifyToken) {
            return false;
        }*/
        //将头像上传到阿里云
        String imageUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        //百度云人脸检测
        boolean result = aipFaceTemplate.detect(imageUrl);
        if (!result) {
//            throw new RuntimeException("图片不合法！");
            throw new BusinessException(ErrorResult.faceError());
        } else {
            /*Claims claims = JwtUtils.getClaims(token);
            Integer id = (Integer) claims.get("id");*/
            UserInfo userInfo = new UserInfo();
            //userInfo.setId(Long.valueOf(id));
            userInfo.setId(UserHolder.getUserId());
            userInfo.setAvatar(imageUrl);
            userInfoApi.update(userInfo);
            return true;
        }
    }

    /**
     * 根据id获取用户信息
     *
     * @param token
     * @param userID
     * @return
     */
    public UserInfoVO users(String token, Long userID) {
        /*boolean result = JwtUtils.verifyToken(token);
        if (!result) {
            return null;
        }
        Claims claims = JwtUtils.getClaims(token);
        Integer id = (Integer) claims.get("id");*/
        if (userID == null) {
            //userID = Long.valueOf(id);
            userID = UserHolder.getUserId();
        }
        UserInfo userInfo = userInfoApi.selectById(userID);
        UserInfoVO userInfoVO = new UserInfoVO();
        //copyProperties只会复制同名称同类型的属性
        BeanUtils.copyProperties(userInfo, userInfoVO);
        Integer age = userInfo.getAge();
        if (age != null) {
            userInfoVO.setAge(String.valueOf(age));
        }
        return userInfoVO;
    }

    /**
     * 修改用户信息
     * @param userInfo
     * @param token
     * @return
     */
    public boolean updateUserInfo(UserInfo userInfo, String token) {
        /*boolean verifyToken = JwtUtils.verifyToken(token);
        if (!verifyToken) {
            return false;
        }*/
        /*Claims claims = JwtUtils.getClaims(token);
        Integer id = (Integer) claims.get("id");*/
//        userInfo.setId(Long.valueOf(id));
        userInfo.setId(UserHolder.getUserId());
        userInfoApi.update(userInfo);
        return true;
    }

    /**
     * 我的-互相喜欢、喜欢、粉丝、谁看过我 - 翻页列表
     * @param type     1-互相喜欢、2-喜欢、3-粉丝、4-谁看过我
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult queryFriends(String type, Integer page, Integer pagesize, String nickname) {
        Long userId = UserHolder.getUserId();
        List<FriendVO> friendVOs = new ArrayList<>(Collections.emptyList());
        UserInfo infoCondition = new UserInfo();
        infoCondition.setNickname(nickname);
        switch (type) {
            case "4": {
                //查询访客数据
                List<Visitors> visitors = visitorsApi.getVisitors(userId, page, pagesize);
                if (CollUtil.isEmpty(visitors)) {
                    return new PageResult();
                }
                //封装vo对象
                List<Long> userIds = CollUtil.getFieldValues(visitors, "visitorUserId", Long.class);
                Map<Long, UserInfo> infoMap = userInfoApi.selectByIdsAndCondition(userIds, null);
                Map<Long, Userlike> likeMap = userLikeApi.selectByIds(userId, userIds);
                for (Visitors visitor : visitors) {
                    UserInfo userInfo = infoMap.get(visitor.getVisitorUserId());
                    Userlike userlike = likeMap.get(visitor.getVisitorUserId());
                    FriendVO friendVO = new FriendVO();
                    //从UserInfo获取matchRate
                    if (ObjectUtil.isNotEmpty(userInfo)) {
                        BeanUtils.copyProperties(userInfo, friendVO);
                        friendVO.setMatchRate(visitor.getScore().intValue());
                    }
                    //从UserLike获取alreadyLove
                    if (ObjectUtil.isNotEmpty(userlike)) {
                        friendVO.setAlreadyLove(userlike.getIsLike());
                    }
                    //添加vo对象到集合
                    friendVOs.add(friendVO);
                }
                //向redis存入查看时间
                String key = Constants.VISITORS_USER;
                String hashKey = userId.toString();
                String value = String.valueOf(System.currentTimeMillis());
                redisTemplate.opsForHash().put(key, hashKey, value);
                break;
            }
            case "3": {
                //查询粉丝数据UserLike
                List<Userlike> userlikes = userLikeApi.queryLikesMe(userId);
                if (CollUtil.isEmpty(userlikes)) {
                    return new PageResult();
                }
                //封装vo对象
                List<Long> userIds = CollUtil.getFieldValues(userlikes, "userId", Long.class);
                Map<Long, UserInfo> infoMap = userInfoApi.selectByIdsAndCondition(userIds, infoCondition);
                List<Long> pageIds = getPageIds(page, pagesize, infoMap);
                Map<Long, RecommendUser> recommendMap = recommendUserApi.selectByIds(userId, userIds);
                Map<Long, Userlike> likeMap = userLikeApi.selectByIds(userId, userIds);
                for (Long id : pageIds) {
                    setFriendVOs(friendVOs, infoMap, recommendMap, likeMap, id);
                }
                break;
            }
            case "2": {
                //查询我喜欢的用户id --》redis
                Set<String> ids = getLoveIds(userId);

                if (CollUtil.isEmpty(ids)) {
                    return new PageResult();
                }
                List<Long> userIds = new ArrayList<>();
                for (String id : ids) {
                    userIds.add(Long.valueOf(id));
                }
                Map<Long, UserInfo> infoMap = userInfoApi.selectByIdsAndCondition(userIds, infoCondition);
                List<Long> pageIds = getPageIds(page, pagesize, infoMap);
                Map<Long, RecommendUser> recommendMap = recommendUserApi.selectByIds(userId, userIds);
                Map<Long, Userlike> likeMap = userLikeApi.selectByIds(userId, userIds);
                for (Long id : pageIds) {
                    setFriendVOs(friendVOs, infoMap, recommendMap, likeMap, id);
                }
                break;
            }
            case "1": {
                //查询我喜欢的用户id和喜欢我的用户id --》redis
                List<Long> userIds = geteachLoveIds(userId);
                if (CollUtil.isEmpty(userIds)) {
                    return new PageResult();
                }
                Map<Long, UserInfo> infoMap = userInfoApi.selectByIdsAndCondition(userIds, infoCondition);
                List<Long> pageIds = getPageIds(page, pagesize, infoMap);
                Map<Long, RecommendUser> recommendMap = recommendUserApi.selectByIds(userId, userIds);
                Map<Long, Userlike> likeMap = userLikeApi.selectByIds(userId, userIds);
                for (Long id : pageIds) {
                    setFriendVOs(friendVOs, infoMap, recommendMap, likeMap, id);
                }
                break;
            }
            default:
                break;
        }
        return new PageResult(page, pagesize, 0, friendVOs);
    }

    /**
     * 分页
     * @param page
     * @param pagesize
     * @param infoMap
     * @return
     */
    private List<Long> getPageIds(Integer page, Integer pagesize, Map<Long, UserInfo> infoMap) {
        Set<Long> infoIds = infoMap.keySet();
        List<Long> ids = infoIds.stream()
                .skip((page - 1) * pagesize)
                .limit(pagesize)
                .collect(Collectors.toList());
        return ids;
    }

    /**
     * 我的-粉丝-喜欢
     * @param uid
     */
    public void fans(Long uid) {
        tanhuaService.love(uid, true);
    }

    /**
     * 我的-喜欢-取消喜欢
     * @param uid
     */
    public void removeLove(Long uid) {
        tanhuaService.love(uid, false);
    }

    /**
     * 我的-互相喜欢，喜欢，粉丝 - 统计
     * @return
     */
    public CountsVO getCounts() {
        Long userId = UserHolder.getUserId();
        CountsVO countsVO = new CountsVO();
        //互相喜欢的数量
        List<Long> eachLoveIds = geteachLoveIds(userId);
        if (CollUtil.isNotEmpty(eachLoveIds)) {
            countsVO.setEachLoveCount(eachLoveIds.size());
        }
        //查询我喜欢的用户数量
        Set<String> loveIds = getLoveIds(userId);
        if (CollUtil.isNotEmpty(loveIds)) {
            countsVO.setLoveCount(loveIds.size());
        }
        //查询我的粉丝数量
        List<Userlike> userlikes = userLikeApi.queryfanCount(userId);
        if (CollUtil.isNotEmpty(userlikes)) {
            countsVO.setFanCount(userlikes.size());
        }
        return countsVO;
    }

    /**
     * 从redis查询我喜欢的用户id集合
     * @param userId
     * @return
     */
    private Set<String> getLoveIds(Long userId) {
        String loveKey = Constants.USER_LOVE_KEY + userId;
        return redisTemplate.opsForSet().members(loveKey);
    }

    /**
     * 从redis查询互相喜欢的用户id
     * @param userId
     * @return
     */
    private List<Long> geteachLoveIds(Long userId) {
        String myLoveKey = Constants.USER_LOVE_KEY + userId;
        Set<String> myLoveIds = redisTemplate.opsForSet().members(myLoveKey);
        List<Long> userIds = new ArrayList<>();
        for (String id : myLoveIds) {
            String loveMeKey = Constants.USER_LOVE_KEY + id;
            Set<String> LoveMeIds = redisTemplate.opsForSet().members(loveMeKey);
            for (String loveMeId : LoveMeIds) {
                String userIdStr = userId.toString();
                if (userIdStr.equals(loveMeId)) {
                    userIds.add(Long.valueOf(id));
                }
            }
        }
        return userIds;
    }

    /**
         * 封装FriendVOs
         * @param friendVOs
         * @param infoMap
         * @param recommendMap
         * @param likeMap
         * @param id
         */
        private void setFriendVOs (
                List < FriendVO > friendVOs,
                Map < Long, UserInfo > infoMap,
                Map < Long, RecommendUser > recommendMap,
                Map < Long, Userlike > likeMap,
                Long id){
            UserInfo userInfo = infoMap.get(id);
            RecommendUser recommendUser = recommendMap.get(id);
            Userlike like = likeMap.get(id);
            FriendVO friendVO = new FriendVO();
            if (ObjectUtil.isNotEmpty(userInfo)) {
                BeanUtils.copyProperties(userInfo, friendVO);
            }
            if (ObjectUtil.isNotEmpty(recommendUser)) {
                friendVO.setMatchRate(recommendUser.getScore().intValue());
            } else {
                Integer matchRate = RandomUtil.randomInt(60, 100);
                friendVO.setMatchRate(matchRate);
            }
            if (ObjectUtil.isNotEmpty(like)) {
                friendVO.setAlreadyLove(like.getIsLike());
            }
            friendVOs.add(friendVO);
        }
}
